/*
 * @Author: liusheng
 * @Date: 2022-06-26 19:47:13
 * @LastEditors: liusheng
 * @LastEditTime: 2022-06-26 19:47:16
 * @Description: 剑指 Offer II 087. 复原 IP 
 * email:liusheng613@126.com
 * Copyright (c) 2022 by liusheng/liusheng, All Rights Reserved. 
 剑指 Offer II 087. 复原 IP 
给定一个只包含数字的字符串 s ，用以表示一个 IP 地址，返回所有可能从 s 获得的 有效 IP 地址 。你可以按任何顺序返回答案。

有效 IP 地址 正好由四个整数（每个整数位于 0 到 255 之间组成，且不能含有前导 0），整数之间用 '.' 分隔。

例如："0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址，但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

 

示例 1：

输入：s = "25525511135"
输出：["255.255.11.135","255.255.111.35"]
示例 2：

输入：s = "0000"
输出：["0.0.0.0"]
示例 3：

输入：s = "1111"
输出：["1.1.1.1"]
示例 4：

输入：s = "010010"
输出：["0.10.0.10","0.100.1.0"]
示例 5：

输入：s = "10203040"
输出：["10.20.30.40","102.0.30.40","10.203.0.40"]
 

提示：

0 <= s.length <= 3000
s 仅由数字组成
 

注意：本题与主站 93 题相同：https://leetcode-cn.com/problems/restore-ip-addresses/ 

通过次数11,579提交次数18,511
 */

#include "header.h"
class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        vector<int> prefix(4,0);
        vector<string> result;
        addValidIpAddresses(s,0,0,s.size(),prefix,result);
        return result;
    }
private:
    //dfs
    void addValidIpAddresses(const string &s,int curIndex,int segId,int totalSize,vector<int> & prefix,vector<string> & result)
    {
        if (segId == SEG_COUNT)
        {
            if (curIndex == totalSize)
            {
                string ip;
                for (int i = 0; i < SEG_COUNT; ++i)
                {
                    ip += to_string(prefix[i]);
                    if (i != SEG_COUNT - 1)
                    {
                        // ip.push_back('.');
                        ip += '.';
                    }
                }
                // printf("ip = %s\n",ip.c_str());
                result.push_back(move(ip));
            }
            return;
        }

        // 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯
        if(curIndex == totalSize)
        {
            return;
        }

        // 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0
        if (s[curIndex] == '0')
        {
            prefix[segId] = 0;
            addValidIpAddresses(s,curIndex + 1,segId + 1,totalSize,prefix,result);
        }

        int addr = 0;
        for (int i = curIndex; i < totalSize; ++i)
        {
            addr = addr * 10 + (s[i] - '0');
            if (addr > 0 && addr <= 255)
            {
                prefix[segId] = addr;
                addValidIpAddresses(s,i + 1,segId + 1,totalSize,prefix,result);
            }
            else
            {
                break;
            }
        }
    }
private:
    static constexpr int SEG_COUNT = 4;
};
